import { Message} from 'element-ui'
import { getFirm , getUserType, getUserAction } from './auth'
import { fetchDetail } from '@/api/table'
import { _ } from 'core-js'
/**
 * Created by jiachenpan on 16/11/18.
 */

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string}
 */
export function parseTime (time, cFormat) {
  if (arguments.length === 0) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
      time = parseInt(time)
    }
    if ((typeof time === 'number') && (time.toString().length === 10)) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const weekNumbers = ['日', '一', '二', '三', '四', '五', '六']
  const timeStr = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return weekNumbers[value]
    }
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return timeStr
}

/**
 * @param {number} time
 * @param {string} option
 * @returns {string}
 */
export function formatTime (time, option) {
  if (('' + time).length === 10) {
    time = parseInt(time) * 1000
  } else {
    time = +time
  }
  const d = new Date(time)
  const now = Date.now()

  const diff = (now - d) / 1000

  if (diff < 30) {
    return '刚刚'
  } else if (diff < 3600) {
    // less 1 hour
    return Math.ceil(diff / 60) + '分钟前'
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + '小时前'
  } else if (diff < 3600 * 24 * 2) {
    return '1天前'
  }
  if (option) {
    return parseTime(time, option)
  } else {
    return (
      d.getMonth() +
      1 +
      '月' +
      d.getDate() +
      '日' +
      d.getHours() +
      '时' +
      d.getMinutes() +
      '分'
    )
  }
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function getQueryObject (url) {
  url = url == null ? window.location.href : url
  const search = url.substring(url.lastIndexOf('?') + 1)
  const obj = {}
  const reg = /([^?&=]+)=([^?&=]*)/g
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1)
    let val = decodeURIComponent($2)
    val = String(val)
    obj[name] = val
    return rs
  })
  return obj
}

/**
 * @param {string} input value
 * @returns {number} output value
 */
export function byteLength (str) {
  // returns the byte length of an utf8 string
  let s = str.length
  for (var i = str.length - 1; i >= 0; i--) {
    const code = str.charCodeAt(i)
    if (code > 0x7f && code <= 0x7ff) s++
    else if (code > 0x7ff && code <= 0xffff) s += 2
    if (code >= 0xDC00 && code <= 0xDFFF) i--
  }
  return s
}

/**
 * @param {Array} actual
 * @returns {Array}
 */
export function cleanArray (actual) {
  const newArray = []
  for (let i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i])
    }
  }
  return newArray
}

/**
 * @param {Object} json
 * @returns {Array}
 */
export function param (json) {
  if (!json) return ''
  return cleanArray(
    Object.keys(json).map(key => {
      if (json[key] === undefined) return ''
      return encodeURIComponent(key) + '=' + encodeURIComponent(json[key])
    })
  ).join('&')
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function param2Obj (url) {
  const search = url.split('?')[1]
  if (!search) {
    return {}
  }
  return JSON.parse(
    '{"' +
      decodeURIComponent(search)
        .replace(/"/g, '\\"')
        .replace(/&/g, '","')
        .replace(/=/g, '":"')
        .replace(/\+/g, ' ') +
      '"}'
  )
}

/**
 * @param {string} val
 * @returns {string}
 */
export function html2Text (val) {
  const div = document.createElement('div')
  div.innerHTML = val
  return div.textContent || div.innerText
}

/**
 * Merges two objects, giving the last one precedence
 * @param {Object} target
 * @param {(Object|Array)} source
 * @returns {Object}
 */
export function objectMerge (target, source) {
  if (typeof target !== 'object') {
    target = {}
  }
  if (Array.isArray(source)) {
    return source.slice()
  }
  Object.keys(source).forEach(property => {
    const sourceProperty = source[property]
    if (typeof sourceProperty === 'object') {
      target[property] = objectMerge(target[property], sourceProperty)
    } else {
      target[property] = sourceProperty
    }
  })
  return target
}

/**
 * @param {HTMLElement} element
 * @param {string} className
 */
export function toggleClass (element, className) {
  if (!element || !className) {
    return
  }
  let classString = element.className
  const nameIndex = classString.indexOf(className)
  if (nameIndex === -1) {
    classString += '' + className
  } else {
    classString =
      classString.substr(0, nameIndex) +
      classString.substr(nameIndex + className.length)
  }
  element.className = classString
}

/**
 * @param {string} type
 * @returns {Date}
 */
export function getTime (type) {
  if (type === 'start') {
    return new Date().getTime() - 3600 * 1000 * 24 * 90
  } else {
    return new Date(new Date().toDateString())
  }
}

/**
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function debounce (func, wait, immediate) {
  let timeout, args, context, timestamp, result

  const later = function () {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last)
    } else {
      timeout = null
      // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args)
        if (!timeout) context = args = null
      }
    }
  }

  return function (...args) {
    context = this
    timestamp = +new Date()
    const callNow = immediate && !timeout
    // 如果延时不存在，重新设定延时
    if (!timeout) timeout = setTimeout(later, wait)
    if (callNow) {
      result = func.apply(context, args)
      context = args = null
    }

    return result
  }
}

/**
 * This is just a simple version of deep copy
 * Has a lot of edge cases bug
 * If you want to use a perfect deep copy, use lodash's _.cloneDeep
 * @param {Object} source
 * @returns {Object}
 */
export function deepClone (source) {
  if (!source && typeof source !== 'object') {
    throw new Error('error arguments', 'deepClone')
  }
  const targetObj = source.constructor === Array ? [] : {}
  Object.keys(source).forEach(keys => {
    if (source[keys] && typeof source[keys] === 'object') {
      targetObj[keys] = deepClone(source[keys])
    } else {
      targetObj[keys] = source[keys]
    }
  })
  return targetObj
}

/**
 * @param {Array} arr
 * @returns {Array}
 */
export function uniqueArr (arr) {
  return Array.from(new Set(arr))
}

/**
 * @returns {string}
 */
export function createUniqueString () {
  const timestamp = +new Date() + ''
  const randomNum = parseInt((1 + Math.random()) * 65536) + ''
  return (+(randomNum + timestamp)).toString(32)
}

/**
 * Check if an element has a class
 * @param {HTMLElement} elm
 * @param {string} cls
 * @returns {boolean}
 */
export function hasClass (ele, cls) {
  return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
}

/**
 * Add class to element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function addClass (ele, cls) {
  if (!hasClass(ele, cls)) ele.className += ' ' + cls
}

/**
 * Remove class from element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function removeClass (ele, cls) {
  if (hasClass(ele, cls)) {
    const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
    ele.className = ele.className.replace(reg, ' ')
  }
}

/**
 * 
 * @param {*} source 用来转换label的数据源
 * @param {*} val 取值
 */

export function handleFormLabels(source,val){
  if (val === undefined || val === null){
    return ''
  }
  if(typeof val === 'number'){
      return source[val]
  }
  let str = []
  val = val.toString().split(',')
  val.map(key=>{
    str.push(source[key])
  })
  return str.join('/')
}

/**
 * 
 * @param {*} _static   需要统计的数据项
 * @param {*} _list     操作的数据源
 * @param {*} _fill     需要改变名称的字段
 * @param {*} _bool     统计单例的数据
 */
export function handleStatic(_static,_list,_fill,_bool){
  console.log(_static,_list,_fill,_bool)
  // 计算请求回的数据中每一家公司的统计数据
  let companyTotal = {}
  //  每往数组中插入一个值时下一次插入值的index就会+1
  let insertIndex = 1
  // 记录需要统计的值，值的类型分为可计算（求和）和不可计算的（日期等），校验属于哪一种类型的值在往对应的属性下面塞
  let tempStatic = {}
  let totalStatic = {}
  _static.map(key=>{
    tempStatic[key] = 0
    totalStatic[key] = 0
  })
  // 计算需要插入的数据
  _list.map((item,index)=>{
    //将当前列字段的数据和前一列的进行相加
    _static.map(key=>{
      if(item[key]-0){
        tempStatic[key] += item[key]
      }else{
        tempStatic[key] = item[key]
      }
    })
    // 将某一家公司的统计数据塞入统计对象中，重置统计对象
    if(item.company_id!=(_list[index+1]&&_list[index+1].company_id)){
      // 这个筛入的span 5用于计算需要合并多少行的，先不考虑合并行的工作
      companyTotal[index+insertIndex] = {...tempStatic,span:5}
      companyTotal[index+insertIndex++][_fill] = '小计'
      _static.map(key=>{
        tempStatic[key] = 0
      })
    }
  })
  // 只计算一次求和
  if(_bool){
    companyTotal[1+insertIndex] = {...tempStatic,span:5}
    companyTotal[1+insertIndex++][_fill] = '小计'
  }
  // 把各公司的统计塞到数组中
  Object.keys(companyTotal).map(key=>{
    _list.splice(key+1,0,companyTotal[key])
  })
  // 计算总的合计数据
  Object.keys(companyTotal).map(keys=>{
    let companyStatic = companyTotal[keys]
    _static.map(key=>{
      if(companyStatic[key]-0){
        totalStatic[key] += companyStatic[key]
      }else{
        totalStatic[key] = companyStatic[key]
      }
    })
  })
  totalStatic[_fill] = '总计'
  _list.splice(_list.length,0,totalStatic)
}

/**
 * 
 * @param {*} _static   需要统计的数据项
 * @param {*} _list     操作的数据源
 * @param {*} _fill     需要改变名称的字段
 * @param {*} _compare  用于比较
 */
export function handleReport (_static,_list,_fill,_compare,) {
  //一共有多少需要有小计项的数据 
  let fill_group = []
  //总计数据
  let total_data = {}
  //统计后的数据
  let return_list = []
  let _small = {}
  let _index = 0
  // 记录当前统计公司对象
  let pointer = ''
  _static.map(key=>{
    total_data[key] = 0;
    _small[key] = 0;
  })
  _list.map(item=>{
    if(fill_group.indexOf(item[_compare])==-1){
      fill_group.push(item[_compare])
    }
    return_list.push(item)
    // 统计总计数据
    _static.map(key=>{
      total_data[key] += (item[key]-0);
    })
  })
  total_data[_fill] = '总计'
  _list.map((item,index)=>{
    if(index==0){
      pointer = item[_compare]
      _static.map(key=>{
        _small[key] += (item[key]-0);
      })
      if(index === _list.length-1){
        _small[_fill]='小计'
        return_list.push({..._small})
        _static.map(key=>{
          _small[key] = 0
        })
      }
    }else if (index ==_list.length-1){
      if(pointer!=item[_compare]){
        _small[_fill]='小计'
        return_list.splice(index+_index++,0,{..._small})
        _static.map(key=>{
          _small[key] = 0
        })
        pointer = item[_compare]
      }
      _static.map(key=>{
        _small[key] += (item[key]-0);
      })
      _small[_fill]='小计'
      return_list.push({..._small})
      _static.map(key=>{
        _small[key] = 0
      })
      pointer = item[_compare]
    }else{
      if(pointer!=item[_compare]){
        _small[_fill]='小计'
        return_list.splice(index+_index++,0,{..._small})
        _static.map(key=>{
          _small[key] = 0
        })
        _static.map(key=>{
          _small[key] += (item[key]-0);
        })
        pointer = item[_compare]
      }else{
        _static.map(key=>{
          _small[key] += (item[key]-0);
        })
      }
    }
  })
  return_list.push({...total_data})
  return return_list
}

/**
 * 根据登录的账号类型在查询或者新增时塞入公司id信息
 * @param {*} _obj 
 */
export function handleSetFirm(_obj){
  _obj[getUserType() + '_id'] = parseInt(getFirm())
}

/**
 * 校验用户输入
 * @param {*} _enter 输入
 * @param {*} _test 校验规则
 */
export function handleVerifyEnter (_enter,_test){
  // 整型数据校验
  if(_test.toString()=='/^[0-9]*[1-9][0-9]*$/'){
    var strArr = []
    for(let i = 0 ; i<_enter.length ; i++){
      strArr.push(_enter[i])
    }
    let tempStr = strArr.join('')
    if(!_test.test(tempStr)&&tempStr!==''){
      strArr.pop()
      let _str = strArr.join('')
      tempStr = handleVerifyEnter(_str,_test)
    }
    return tempStr
    // 浮点类型数据校验
  }else if(_test.toString()==/^(\d+|\d+\.\d{1,2})$/.toString()){
    let entArr = _enter.split('.')
    if(entArr.length>2){
      entArr.length = 2
    }
    if(entArr.length == 2 && parseInt(entArr[1])+1){
      return entArr[0].replace(/[^\d.]/g,'') + '.' + entArr[1].replace(/[^\d.]/g,'').substring(0,3)
    }else if(entArr.length == 2 && isNaN(parseInt(entArr[1]))){
      return entArr[0].replace(/[^\d.]/g,'') + '.'
    }else{
      return entArr[0].replace(/[^\d.]/g,'')
    }
  }else if(_test.toString()==/^\d{1,2}(\.\d+)?$/.toString()){    //100以内的数字
    let entArr = _enter.split('.')
    if(entArr.length>2){
      entArr.length = 2
    }
    if(entArr.length == 2 && parseInt(entArr[1])+1){
      return entArr[0].substring(0,2).replace(/[^\d.]/g,'') + '.' + entArr[1].replace(/[^\d.]/g,'').substring(0,3)
    }else if(entArr.length == 2 && isNaN(parseInt(entArr[1]))){
      return entArr[0].substring(0,2).replace(/[^\d.]/g,'') + '.'
    }else{
      if(entArr[0].length>=2){
        entArr[0] = entArr[0].substring(0,2)
      }
      return entArr[0].replace(/[^\d.]/g,'')
    }
  }
}

/**
 * 校验用户操作权限
 * @param {*} _name 页面名称
 * @param {*} _action 页面操作
 */
export function handleActionRoot (_name,_action){
  let user_action = JSON.parse(getUserAction())
  if (!Object.keys(user_action).length){
    return true
  }
  if(_name&&_action){
    if(user_action[_name]&&(user_action[_name]&&user_action[_name][_action])){
      return true
    }else{
      return false
    }
  }else if (_name&&_action==null){
    if(user_action[_name]){
      return true
    }else{
      return false
    }
  }
}

/**
 * 校验用户的按钮操作权限
 * @param {*} _obj 参数对象
 */
export function handleActionPermission (_obj){
  let user_action = JSON.parse(getUserAction())
  if (!Object.keys(user_action).length){
    return true
  }
  if(_obj._name&&_obj._action){
    if(user_action[_obj._name]&&(user_action[_obj._name]&&user_action[_obj._name][_obj._action])){
      return true
    }else{
      return false
    }
  }else if (_obj._name&&_obj._action==null){
    if(user_action[_obj._name]){
      return true
    }else{
      return false
    }
  }
}

/**
 * 
 * @param {*} _cb this.$set
 * @param {*} _obj this.temp
 * @param {*} _keyArr this.config.custom_list
 */
export function stringToNumber (_cb,_obj,_keyArr){
  _keyArr.map(key=>{
    if(_obj[key]){
      _cb(_obj,key,_obj[key].toString().split(',').join(''))
    }else{
      // 当用户清空输入时
      _cb(_obj,key,0)
    }
  })
}
/**
 * 
 * @param {*} _cb 
 * @param {*} _obj 
 * @param {*} _keyArr 
 */
export function numberToString (_cb,_obj,_keyArr){
  _keyArr.map(key=>{
    if(_obj[key]){
      // 减0消除'01'这种串前面的0
      _cb(_obj,key,_obj[key] - 0 + '')
      let num = _obj[key].split(',').join('')
      num = num.split('').reverse()
      let num_string = []
      // 正序往num_string里面塞，如果剩下的长度能被三整除就塞入','
      num.map((item,index)=>{
        num_string.push(item)
        if((index+1)%3 === 0&&num.length-1>index){
          num_string.push(',')
        }
      })
      _cb(_obj,key,num_string.reverse().join(''))
      if(_obj[key].split(',').join('')-0===0){
        _cb(_obj,key,'')
      }
    }
  })
}

export function fileSize (_size) {
  const bite = _size/1024
  const kb = bite/1024
  const m = kb/1024
  var rt_size = ''
  if(m>1){
    rt_size = m.toFixed(1)+'M'
  }else if(kb>1){
    rt_size = kb.toFixed(1)+'KB'
  }else if(bite>1){
    rt_size = bite.toFixed(1)+'字节'
  }
  return rt_size
}

export function calendarFilterDate (_date){
  const currYear = _date.split('-')[0]
  const currMonth = _date.split('-')[1]
  let startDate = ''
  let endDate = ''
  startDate = (currMonth==1?currYear-1:currYear)+'-'+(currMonth==1?12:currMonth-1)+'-20'
  endDate = (currMonth==12?(currYear-0)+1:currYear)+'-'+(currMonth==12?1:(currMonth-0)+1)+'-08'
  return [startDate,endDate]
}